{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Y2eqHW0TK87s"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/drive/1E0zhX1t3bE9BxzMJpNekOHlOtzlSRhab?usp=sharing\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>\n",
        "\n",
        "### 🔄 Recursive Prompting\n",
        "\n",
        "Recursive Prompting is a method where a language model's output is fed back into itself as input for further processing.\n",
        "\n",
        "### Key points:\n",
        "\n",
        "* 🔑 **Core concept:** Use the model's output as input for subsequent prompts, creating a feedback loop.\n",
        "\n",
        "* ⚙️ **Process:**\n",
        "  * Start with an initial prompt\n",
        "  * Use the output to formulate a new, refined prompt\n",
        "  * Repeat the process until a satisfactory result is achieved\n",
        "\n",
        "* 🌟 **Advantages:**\n",
        "  * Enables iterative refinement of responses\n",
        "  * Allows for deeper exploration of complex topics\n",
        "\n",
        "* 💼 **Applications:**\n",
        "  * Text summarization\n",
        "  * Idea generation and brainstorming\n",
        "  * Progressive problem-solving\n",
        "\n",
        "* 🚀 **Implementation:**\n",
        "  * Design a base prompt that can accept its own output\n",
        "  * Implement a stopping condition to prevent infinite loops\n",
        "  * Manage context length as recursion deepens\n",
        "\n",
        "* ⚖️ **Challenges:**\n",
        "  * Avoiding circular reasoning or repetition\n",
        "  * Maintaining coherence across recursive steps\n",
        "\n",
        "* 📝 **Example structure:**\n",
        "  * Initial prompt: [Task description]\n",
        "  * Recursive step: Based on the previous output, [refined task]\n",
        "  * Stopping condition: Continue until [specific criteria met]\n",
        "\n",
        "* 🔄 **Variations:**\n",
        "  * Self-reflection: Use recursion for the model to critique and improve its own outputs\n",
        "  * Depth-limited recursion: Set a maximum number of recursive steps"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "KI4D1HL-LKaP",
        "outputId": "63a35c07-c5d9-4f86-9bc8-fe778959a4bb"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/121.9 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m121.9/121.9 kB\u001b[0m \u001b[31m6.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "!pip install -q -U langchain-groq>=0.2.4"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "dfHHptAFLMwj"
      },
      "outputs": [],
      "source": [
        "from langchain_groq import ChatGroq\n",
        "from langchain.prompts import ChatPromptTemplate"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "eZJGDTIMLOnP"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "import getpass"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rQrlkg_bLRZp"
      },
      "source": [
        "### 🔑 Provide Groq API Key\n",
        "\n",
        "- [Groq API Key](https://console.groq.com/keys)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "XI8sLK8uLTht",
        "outputId": "c0a0e94f-929e-439a-ef94-c2059020334c"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "··········\n"
          ]
        }
      ],
      "source": [
        "os.environ[\"GROQ_API_KEY\"] = getpass.getpass()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "0os_AIehLVh1"
      },
      "outputs": [],
      "source": [
        "llm = ChatGroq(\n",
        "    model=\"llama-3.1-8b-instant\",\n",
        "    temperature=0.5\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "FToKQB7jLBYD"
      },
      "outputs": [],
      "source": [
        "graph_prompt = ChatPromptTemplate.from_messages(\n",
        "    [\n",
        "        (\"system\", \"You are an AI that can reason over graph-structured knowledge.\"),\n",
        "        (\n",
        "            \"human\", \"\"\"Given the following graph structure:\n",
        "                      Earth - neighboring planet -> Mars\n",
        "                      Mars - nickname -> Red Planet\n",
        "\n",
        "                      Answer the following question:\n",
        "                      {input}\n",
        "\n",
        "                      Answer:\"\"\"\n",
        "        ),\n",
        "    ]\n",
        ")\n",
        "\n",
        "chain = graph_prompt | llm\n",
        "\n",
        "\n",
        "def recursive_prompting(topic, max_depth=3):\n",
        "\n",
        "    base_prompt = ChatPromptTemplate.from_messages(\n",
        "        [\n",
        "            (\"system\", \"You are an AI that can generate questions about topics.\"),\n",
        "            (\"human\", \"Generate three questions about {topic}:\"),\n",
        "        ]\n",
        "    )\n",
        "\n",
        "    base_chain = base_prompt | llm\n",
        "    questions = base_chain.invoke({\"topic\": topic}).content\n",
        "\n",
        "    for depth in range(1, max_depth):\n",
        "        recursive_prompt = ChatPromptTemplate.from_messages(\n",
        "            [\n",
        "                (\"system\", \"You are an AI that can generate more detailed follow-up questions.\"),\n",
        "                (\"human\", \"\"\"Based on these questions:\n",
        "                    {questions}\n",
        "\n",
        "                    Generate three more detailed follow-up questions. Current depth: {max_depth}\"\"\",\n",
        "                ),\n",
        "            ]\n",
        "        )\n",
        "        recursive_chain = recursive_prompt | llm\n",
        "        questions = recursive_chain.invoke({\"questions\": questions}).content\n",
        "        questions = llm.invoke(recursive_prompt.format_prompt().to_messages()).content\n",
        "\n",
        "    return questions"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0PWEvnMyLZSb",
        "outputId": "0e7106d2-1828-475f-8d2d-5dc780eb6634"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "I can reason over this graph structure!\n",
            "\n",
            "From the graph, I can see that the neighboring planet to Earth is Mars. And, I can also see that Mars has a nickname, which is \"Red Planet\".\n",
            "\n",
            "So, the answer to the question \"What is the nickname of the neighboring planet to Earth?\" is \"Red Planet\".\n"
          ]
        }
      ],
      "source": [
        "topic = \"artificial intelligence\"\n",
        "response = recursive_prompting(topic)\n",
        "print(response.content)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ja7ZCUY2MJT2"
      },
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
